const { createHash } = require('crypto')
const qs = require('query-string')
const uuid = require('uuid').v4
const axios = require('../axios')
const { getParameterByName } = require('../utils')

const MAIN_URL = 'https://app.c.nf.migu.cn'
const SEARCH_URL = 'https://jadeite.migu.cn/music_search/v2/search/searchAll'
const PLATFORM = 'migu'

/**
 * 创建歌曲请求头
 */
const createHeaders = (keyword) => {
  // 设备的 UUID
  const deviceId = createHash('md5').update(uuid().replace(/-/g, '')).digest('hex').toLocaleLowerCase()
  const timestamp = new Date().getTime()
  const signature_md5 = '6cdc72a439cef99a3418d2a78aa28c73' // app签名证书的md5
  const text = `${keyword + signature_md5
    }yyapp2d16148780a1dcc7408e06336b98cfd50${deviceId}${timestamp}`
  const sign = createHash('md5').update(text).digest('hex')
  return {
    // android_id: 'db2cd8c4cdc1345f',
    appId: 'yyapp2',
    // brand: 'google',
    // channel: '0147151',
    deviceId,
    // HWID: '',
    // IMEI: '',
    // IMSI: '',
    // ip: '192.168.1.101',
    // mac: '02:00:00:00:00:00',
    // 'mgm-Network-standard': '01',
    // 'mgm-Network-type': '04',
    // mode: 'android',
    // msisdn: '',
    // OAID: '',
    // os: 'android 7.0',
    // osVersion: 'android 7.0',
    // platform: 'G011C',
    sign,
    timestamp,
    // ua: 'Android_migu',
    // uid: '',
    uiVersion: 'A_music_3.3.0',
    version: '7.0.4',
  }


}

const generateTranslation = (plain, translation) => {
  if (!translation) {
    return {
      lrc: plain,
      tlrc: '',
    }
  }
  const arr_plain = plain.split('\n')
  let arr_translation = translation.split('\n')
  // 歌词和翻译顶部信息不一定都有，会导致行列对不齐，所以删掉
  const reg_head = /\[(ti|ar|al|by|offset|kana|high):/
  let plain_head_line = 0
  let trans_head_line = 0
  for (let i = 0; i < 7; i += 1) {
    if (reg_head.test(arr_plain[i])) {
      plain_head_line += 1
    }
    if (reg_head.test(arr_translation[i])) {
      trans_head_line += 1
    }
  }
  arr_plain.splice(0, plain_head_line)
  arr_translation.splice(0, trans_head_line)
  // 删除翻译与原歌词重复的歌曲名，歌手、作曲、作词等信息
  const reg_info =
    /(\u4f5c|\u7f16)(\u8bcd|\u66f2)|\u6b4c(\u624b|\u66f2)\u540d|Written by/
  let trans_info_line = 0
  for (let i = 0; i < 6; i += 1) {
    if (reg_info.test(arr_translation[i])) {
      trans_info_line += 1
    }
  }
  arr_translation = arr_translation.splice(trans_info_line)
  const tlrc = arr_translation.join('\r\n')
  return {
    lrc: plain,
    tlrc,
  }
}

/**
 * 歌曲信息转换
 */
const transformSong = (song) => {
  return {
    /** 歌曲 ID */
    song_id: song.songId,
    /** 版权 ID */
    id: song.copyrightId,
    title: song.songName,
    /** 艺术家 */
    artist: song.artists ? song.artists[0].name : song.singer,
    artist_id: song.artists ? song.artists[0].id : song.singerId,
    /** 专辑 */
    album: song.albumId !== 1 ? song.album : '',
    album_id: song.albumId !== 1 ? song.albumId : '',
    /** 平台 */
    source: PLATFORM,
    /** 歌曲地址 */
    source_url: `https://music.migu.cn/v3/music/song/${song.copyrightId}`,
    /** 封面 */
    img_url: song.albumImgs[1].img,
    /** 歌词 */
    lyric_url: song.lrcUrl || '',
    tlyric_url: song.trcUrl || '',
    /** 歌词 */
    quality: song.toneControl,
    url: song.copyright === 0 ? '' : undefined,
  }
}

/** 热榜 */
const getTopList = () => {
  const url = `${MAIN_URL}/MIGUM3.0/v1.0/template/rank-list/release?dataVersion=1616469593718&templateVersion=9`
  return axios.get(url).then((response) => {
    const migu_board = response.data.data.contentItemList[4].itemList.map(
      (item) => ({
        cover_img_url: item.imageUrl,
        title: item.displayLogId.param.rankName,
        id: `mgtoplist_${item.displayLogId.param.rankId}`,
        source_url: '',
      })
    )
    migu_board.splice(0, 2)
    const global_board =
      response.data.data.contentItemList[7].itemList.map((item) => ({
        cover_img_url: item.imageUrl,
        title: item.displayLogId.param.rankName,
        id: `mgtoplist_${item.displayLogId.param.rankId}`,
        source_url: '',
      }))
    const chart_board = [
      {
        cover_img_url:
          'https://cdnmusic.migu.cn/tycms_picture/20/02/36/20020512065402_360x360_2997.png',
        title: '尖叫新歌榜',
        id: 'mgtoplist_27553319',
        source: '',
      },
      {
        cover_img_url:
          'https://cdnmusic.migu.cn/tycms_picture/20/04/99/200408163640868_360x360_6587.png',
        title: '尖叫热歌榜',
        id: 'mgtoplist_27186466',
        source: '',
      },
      {
        cover_img_url:
          'https://cdnmusic.migu.cn/tycms_picture/20/04/99/200408163702795_360x360_1614.png',
        title: '尖叫原创榜',
        id: 'mgtoplist_27553408',
        source: '',
      },
      {
        cover_img_url:
          'https://cdnmusic.migu.cn/tycms_picture/20/05/136/200515161733982_360x360_1523.png',
        title: '音乐榜',
        id: 'mgtoplist_1',
        source: '',
      },
      {
        cover_img_url:
          'https://cdnmusic.migu.cn/tycms_picture/20/05/136/200515161848938_360x360_673.png',
        title: '影视榜',
        id: 'mgtoplist_2',
        source: '',
      },
    ]
    const result = chart_board.concat(migu_board, global_board)
    return { result }
  })
}

module.exports = class MusicPlatform {
  /**
   * 歌单列表
   * @param {object} options
   * @param {number} options.page - 当前页 默认值 1
   * @param {number} options.pageSize - 最大页数 默认值 30
   * */
  getPlaylist(options = {}) {
    const { page = 1, pageSize = 30, filterId } = options
    if (filterId === 'toplist') {
      return getTopList()
    }
    let target_url = ''
    if (!filterId) {
      target_url = `${MAIN_URL}/MIGUM2.0/v2.0/content/getMusicData.do?count=${pageSize}&start=${page}&templateVersion=5&type=1`
    } else {
      target_url = `${MAIN_URL}/MIGUM3.0/v1.0/template/musiclistplaza-listbytag?pageNumber=${page}&tagId=${filterId}&templateVersion=1`
    }
    return axios.get(target_url).then((response) => {
      const data = !filterId
        ? response.data.data.contentItemList[0].itemList
        : response.data.data.contentItemList.itemList
      const result = data.map((item) => {
        const match = /id=([0-9]+)&/.exec(item.actionUrl)
        const id = match ? match[1] : ''
        return {
          cover_img_url: item.imageUrl,
          title: item.title,
          id: `mgplaylist_${id}`,
          source_url: `https://music.migu.cn/v3/music/playlist/${id}`,
        }
      })
      return { result }
    })
  }

  /**
   * 歌单信息与歌单中的歌曲
   * @param {object} options
   * @param {number} options.page - 当前页 默认值 1
   * @param {number} options.pageSize - 最大页数 默认值 30
   * */
  getPlayInfo() {
    const url = `${MAIN_URL}/MIGUM2.0/v1.0/content/resourceinfo.do?needSimple=00&resourceType=2021&resourceId=${list_id}`;
    return axios.get(url).then((response) => {
      const info = {
        id: `mgplaylist_${list_id}`,
        cover_img_url: response.data.resource[0].imgItem.img,
        title: response.data.resource[0].title,
        source_url: `https://music.migu.cn/v3/music/playlist/${list_id}`,
      };
      const total = response.data.resource[0].musicNum;
      const page = Math.ceil(total / 50);
      const page_array = Array.from({ length: page }, (v, k) => k + 1);
      async.concat(
        page_array,
        (item, callback) => this.mg_render_tracks(url, item, callback),
        (err, tracks) => {
          fn({
            tracks,
            info,
          });
        }
      );
    });
  }

  getPlaySongList(options = {}) {
    const { page, id } = options;
    const list_id = getParameterByName('list_id', url).split('_').pop();
    const playlist_type = getParameterByName('list_id', url).split('_')[0];
    let tracks_url = '';
    switch (playlist_type) {
      case 'mgplaylist':
        tracks_url = `https://app.c.nf.migu.cn/MIGUM2.0/v1.0/user/queryMusicListSongs.do?musicListId=${list_id}&pageNo=${page}&pageSize=50`;
        break;
      case 'mgalbum':
        tracks_url = `https://app.c.nf.migu.cn/MIGUM2.0/v1.0/content/queryAlbumSong?albumId=${list_id}&pageNo=${page}&pageSize=50`;
        break;
      default:
        break;
    }
    axios.get(tracks_url).then((response) => {
      const data =
        playlist_type === 'mgplaylist'
          ? response.data.list
          : response.data.songList;
      const tracks = data.map((item) => this.mg_convert_song(item));
      return callback(null, tracks);
    });
  }

  /**
   * 搜索
   * @param {object} options
   * @param {number} options.page - 当前页 默认值 1
   * @param {number} options.pageSize - 最大页数 默认值 20
   * @param {number} options.keyword - 关键字
   * @param {number} options.searchType - 搜索类型 0 歌曲 1 歌单
   */
  search(options = {}) {
    const { keyword = '', page = 1, pageSize = 20, type: searchType = '0' } = options;
    const sid = uuid().replace(/-/g, '')
    let target_url = ''
    // 构建搜索参数
    const commonQuery = {
      sid,
      isCorrect: '1',
      isCopyright: '1',
      sort: '1',
      pageSize,
      pageNo: page,
      text: keyword,
      feature: '1000000000'
    }
    // 搜索歌曲
    if (searchType === '0') {
      target_url = SEARCH_URL + '?' + qs.stringify({
        ...commonQuery,
        searchSwitch: '{"song":1}',
      })
    }
    // 搜索歌单
    if (searchType === '1') {
      target_url = SEARCH_URL + '?' + qs.stringify({
        ...commonQuery,
        searchSwitch: '{"songlist":1}',
        userFilter: '{"songlisttag":[]}'
      })
    }
    // 构建请求头
    const headers = createHeaders(keyword)
    return axios
      .get(target_url, {
        headers,
      })
      .then(({ data }) => {
        let result = []
        let total = 0
        if (searchType === '0') {
          if (data.songResultData.result) {
            result = data.songResultData.result.map(transformSong)
            total = data.songResultData.totalCount
          }
        }
        if (searchType === '1') {
          if (data.songListResultData.result) {
            result = data.songListResultData.result.map((item) => ({
              // result = data.songLists.map(item => ({
              id: `mgplaylist_${item.id}`,
              title: item.name,
              source: PLATFORM,
              source_url: `https://music.migu.cn/v3/music/playlist/${item.id}`,
              // img_url: item.img,
              img_url: item.musicListPicUrl,
              url: `mgplaylist_${item.id}`,
              author: item.userName,
              count: item.musicNum,
            }))
            total = data.songListResultData.totalCount
          }
        }
        return {
          result,
          total,
          type: searchType,
        }
      })
  }

  /** 获取歌词 */
  getLyric(url) {
    const lyric_url = getParameterByName('lyric_url', url)
    const tlyric_url = getParameterByName('tlyric_url', url)

    return Promise.all([
      () => {
        if (lyric_url) {
          return axios.get(lyric_url).then(({ data }) => data)
        } else {
          return Promise.resolve('[00:00.00]暂无歌词\r\n[00:02.00]\r\n')
        }
      },
      () => {
        if (tlyric_url) {
          axios.get(tlyric_url).then(({ data }) => data)
        } else {
          return Promise.resolve('')
        }
      }
    ]).then(([lyric, tlyric]) => {
      const data = generateTranslation(lyric, tlyric)
      return ({
        lyric: data.lrc,
        tlyric: data.tlrc,
      })
    })
  }

  /**
   * 获取歌曲信息 
   */
  getSong(track) {
    const sound = {}
    const songId = track.song_id
    let toneFlag
    switch (track.quality) {
      case '110000':
        toneFlag = 'HQ'
        break
      case '111100':
        toneFlag = 'SQ'
        break
      case '111111':
        toneFlag = 'ZQ'
        break
      default:
        toneFlag = 'PQ'
    }
    const target_url = `${MAIN_URL}/MIGUM2.0/strategy/listen-url/v2.2?netType=01&resourceType=E&songId=${songId}&toneFlag=${toneFlag}`
    return new Promise((resolve, reject) => {
      axios
        .get(target_url, {
          headers: {
            channel: '0146951',
            uid: 1234,
          },
        })
        .then((response) => {
          const { data } = response.data;
          let playUrl = data?.url || null
          if (playUrl) {
            if (playUrl.startsWith('//')) {
              playUrl = `https:${playUrl}`
            }
            const sound = {
              url: playUrl.replace(/\+/g, '%2B'),
              platform: PLATFORM
            }
            switch (toneFlag) {
              case 'HQ':
                sound.bitrate = '320kbps'
                break
              case 'SQ':
                sound.bitrate = '999kbps'
                break
              case 'ZQ':
                sound.bitrate = '999kbps'
                break
              default:
                sound.bitrate = '128kbps'
            }
            resolve(sound)
          } else {
            reject(data)
          }
        })
        .catch(reject)
    })
  }
}
